<?php

namespace app\user\logic;

use app\common\exception\LogicException;
use app\model\Barn;
use app\model\Disinfect;
use app\model\FeedPlan;
use app\model\FourteenFeedPlan;
use app\model\PigDailyEat;
use app\model\Fence;
use app\model\Pig;
use app\model\PigWeight;
use think\db\Query;

class FenceLogic
{
    /**
     * @Description 列表
     * @param array $param
     * @time 2023/08/26 18:06:45
     * @return mixed
     * @author: zj
     */
    public function getList(array $param)
    {
        $factoryId = request()->user_info['factory_id'];
        $fenceModel = new Fence();
        $query = $fenceModel->alias('fe')
            ->leftJoin("barn b", "b.id = fe.out_barn_id")
            ->leftJoin("factory fa", "fa.id = fe.factory_id")
            ->field("fe.out_id as id,fe.name,fe.out_barn_id as barn_id,b.name as barn,fe.factory_id,fe.status,fa.address,fa.contacts,fa.phone,fe.record_time,fe.create_time")
            ->where("fe.factory_id", $factoryId)
            ->where("fe.delete_time", $fenceModel::IS_DELETE_NO);
        if ($param['name']) {
            $query->where("fe.name", "LIKE", "%" . trim($param['name']) . "%");
        }
        if ($param['barn_id']) {
            $query->where("fe.out_barn_id", $param['barn_id']);
        }
        if (!empty($param['status'])) {
            $query->where("fe.status", $param);
        }
        if ($param['record_time_start']) {
            $query->where("fe.record_time", ">=", $param['record_time_start']);
        }
        if ($param['record_time_end']) {
            $query->where("fe.record_time", "<=", $param['record_time_end']);
        }
        $list = $query->order("fe.out_id", "ASC")
            ->paginate([
                "list_rows" => $param['page_size'],
                'page' => $param['page']
            ])
            ->toArray();

        $disinfectModel = new Disinfect();

        foreach ($list['data'] as &$value) {
            $lastDisinfectTime = "";
            $disinfectItem = "";
            $disinfectRemark = "";
            $disinfect = $disinfectModel->getLastDisinfectTime($factoryId,0,$value['id']);
            if ($disinfect) {
                $lastDisinfectTime = $disinfect['record_time'];
                $disinfectItem = $disinfect['item_name'];
                $disinfectRemark = $disinfect['remark'];
            }
            $value['last_disinfect_time'] = $lastDisinfectTime;
            $value['disinfect_item'] = $disinfectItem;
            $value['disinfect_remark'] = $disinfectRemark;
        }
        unset($value);

        return $list;
    }

    /**
     * @Description 养殖栏(猪栏)详情
     * @author: zj
     * @param int $id
     * @time 2024/03/19 11:51:58
     * @return array
     */
    public function detail(int $id)
    {
        $factoryId = request()->user_info['factory_id'];
        $fenceModel = new Fence();
        // 未传猪栏id
        if ($id == 0) {
            $defaultId = $fenceModel->alias('f')
                ->join('barn b', 'f.out_barn_id = b.id AND b.delete_time = '.Barn::IS_DELETE_NO, 'left')
                ->where("f.factory_id", $factoryId)
                ->where('f.delete_time', $fenceModel::IS_DELETE_NO)
                ->order('f.out_barn_id ASC,f.id ASC')
                ->value('f.out_id');
            if (!$defaultId) {
                throw new LogicException("缺少必要参数id");
            }
            $id = $defaultId;
        }
        $query = $fenceModel->alias('fe')
            ->with([
                'pig' => function (Query $pigQuery) use ($factoryId) {
                    $pigQuery->field('out_id as id,factory_id,out_fence_id,breed as breed_name,tag_address as ear_code,entry_time as in_time,exit_time as out_time,health as status,weight,record_time,create_time')
                        ->where('factory_id', $factoryId)
                        ->where('delete_time', Pig::IS_DELETE_NO)
                        ->where('exit_time', Pig::IS_EXIT_NO);
                }
            ])
            ->leftJoin("factory fa", "fe.factory_id = fa.id")
            ->leftJoin("barn b", "fe.out_barn_id = b.out_id")
            ->field("fe.out_id as id,fe.out_id,fe.name as fence,fe.factory_id,fa.name as factory,fe.out_barn_id as barn_id,b.name as building,fe.status,fe.record_time,fe.create_time")
            ->where("fe.factory_id", $factoryId)
            ->where("fe.out_id", $id)
            ->where("fe.delete_time", $fenceModel::IS_DELETE_NO);
        $info = $query->find();
        if (!$info) {
            throw new LogicException("猪栏不存在");
        }
        $info = $info->toArray();

        // 最近消毒记录
        $dfModel = new Disinfect();
        $lastDisinfect = $dfModel->getLastDisinfectTime($factoryId, 0, $info['id']);
        $info['last_disinfect'] = $lastDisinfect ? date("Y-m-d H:i:s", $lastDisinfect['record_time']) : "";

        $pigModel = new Pig();
        $pigAvgWeight = 0;// 平均体重
        // 猪栏 猪的数量
        $pigCount = $pigModel->checkPigCount($factoryId, $info['barn_id'], $info['id']);
        // 猪栏 猪总体重
        $allWeight = $pigModel->pigWeightTotal($factoryId, $info['barn_id'], $info['id']);

        if ($pigCount) {
            $pigAvgWeight = round($allWeight / $pigCount, 2);
        }

        $weightGainTotal = 0;// 栏中所有猪的总增重量
        $foodIntakeTotal = 0;// 栏中所有猪的总进食量
        if ($info['pig']) {
            $pigWeightModel = new PigWeight();
            $eatModel = new PigDailyEat();
            foreach ($info['pig'] as $key => $value) {
                // 单猪增重量
                $weightGain = $pigWeightModel->checkWeightGain($value['id'], 0, time());
                $weightGainTotal += $weightGain;
                // 单猪进食量
                $foodIntake = $eatModel->checkFoodIntake($value['id'], 0, time());
                $foodIntakeTotal += $foodIntake;
            }
        }
        $ratio = 0;// 料肉比 = 进食量/增重量
        if ($weightGainTotal != 0) {
            $ratio = round($foodIntakeTotal / $weightGainTotal, 2);
        }

        $statisticData = [
            'all_pig_num' => $pigCount,
            'avg_weight' => $pigAvgWeight,
            'weight_gain' => $weightGainTotal,
            'food_intake' => $foodIntakeTotal,
            'ratio' => $ratio
        ];

        return array_merge($info, $statisticData);
    }

    /**
     * @Description 栏详情补充(手机端)
     * @param int $factoryId
     * @param int $id
     * @time 2023/09/19 11:03:04
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * @author: zj
     */
    public function detailSupply(int $factoryId, int $id)
    {
        $fenceModel = new Fence();
        $fence = $fenceModel->alias('f')
            ->with([
                'pig' => function (Query $pigQuery) use ($factoryId) {
                    $pigQuery->where('factory_id', $factoryId)
                        ->where('delete_time', Pig::IS_DELETE_NO)
                        ->where('exit_time', Pig::IS_EXIT_NO);
                }
            ])
            ->field('f.out_id as id,f.out_id,f.name,f.out_barn_id as building_id')
            ->where('f.factory_id', $factoryId)
            ->where('f.delete_time', $fenceModel::IS_DELETE_NO)
            ->find();
        if (!$fence) {
            throw new LogicException("猪栏不存在");
        }
        $fence = $fence->toArray();

        $weightGainTotal1 = 0;// 栏中所有猪的昨天总增重量
        $foodIntakeTotal1 = 0;// 栏中所有猪的昨天总进食量
        $weightGainTotal2 = 0;// 栏中所有猪的今天总增重量
        $foodIntakeTotal2 = 0;// 栏中所有猪的今天总进食量
        $yesterdayWeightTotal = 0; // 今天总体重
        $todayWeightTotal = 0;// 今天总体重

        $yesterdayStartTime = strtotime(date("Y-m-d", strtotime("-1 day"))); // 昨天起始时间戳
        $yesterdayEndTime = $yesterdayStartTime + 86399; // 昨天结束时间戳
        $todayStartTime = strtotime(date("Y-m-d", request()->time())); // 今天起始时间戳
        $todayEndTime = $todayStartTime + 86399; // 今天结束时间戳
        if ($fence['pig']) {
            $pigWeightModel = new PigWeight();
            $eatModel = new PigDailyEat();
            foreach ($fence['pig'] as $key => $value) {
                // 昨天单猪增重量
                $weightGain1 = $pigWeightModel->checkWeightGain($value['out_id'], $yesterdayStartTime, $yesterdayEndTime);
                $weightGainTotal1 += $weightGain1;
                // 昨天单猪进食量
                $foodIntake1 = $eatModel->checkFoodIntake($value['out_id'], $yesterdayStartTime, $yesterdayEndTime);
                $foodIntakeTotal1 += $foodIntake1;
                // 今天单猪增重量
                $weightGain2 = $pigWeightModel->checkWeightGain($value['out_id'], $todayStartTime, $todayEndTime);
                $weightGainTotal2 += $weightGain2;
                // 今天单猪进食量
                $foodIntake2 = $eatModel->checkFoodIntake($value['out_id'], $todayStartTime, $todayStartTime);
                $foodIntakeTotal2 += $foodIntake2;
                // 获取单猪今天最新体重
                $yesterdayWeight = $pigWeightModel->getLastWeight($value['out_id'], $todayEndTime);
                $yesterdayWeightTotal += $yesterdayWeight;
                // 获取单猪最新体重
                $todayWeight = $pigWeightModel->getLastWeight($value['out_id']);
                $todayWeightTotal += $todayWeight;
            }
        }

        $ratio1 = 0;// 昨天 料肉比 = 进食量/增重量
        if ($weightGainTotal1 != 0) {
            $ratio1 = round($foodIntakeTotal1 / $weightGainTotal1, 2);
        }
        $ratio2 = 0;// 今天 料肉比 = 进食量/增重量
        if ($weightGainTotal2 != 0) {
            $ratio2 = round($foodIntakeTotal2 / $weightGainTotal2, 2);
        }
        $ratioChange = $this->compare($ratio1,$ratio2);

        // 统计猪的数量
        $pigModel = new Pig();
        // 今天总猪数
        $yesterdayTotal = $pigModel->checkPigCount($factoryId, $fence['building_id'], $fence['id'], 0, $todayStartTime, $todayEndTime);
        // 今天总猪数
        $todayStartTime = strtotime(date("Y-m-d H:i:s"));
        $todayTotal = $pigModel->checkPigCount($factoryId, $fence['building_id'], $fence['id'], 0, $todayStartTime, time());

        $yesterdayAvgWeight = 0;// 今天平均体重
        $todayAvgWeight = 0;// 今天平均体重
        if ($yesterdayTotal) {
            $yesterdayAvgWeight = round($yesterdayWeightTotal / $yesterdayTotal, 2);
        }
        if ($todayTotal) {
            $todayAvgWeight = round($todayWeightTotal / $todayTotal, 2);
        }
        $avgWeightChange = $this->compare($yesterdayAvgWeight,$todayAvgWeight);

        // 全部猪
        $all = $pigModel->checkPigCount($factoryId, 0, $id);
        // 健康猪数量
        $health = $pigModel->checkPigCount($factoryId, 0, $id, $pigModel::STATUS_HEALTH);
        // 疑似健康
        $mayBeHealth = $pigModel->checkPigCount($factoryId, 0, $id, $pigModel::STATUS_POTENTIAL_HEALTH);
        // 生病
        $sick = $pigModel->checkPigCount($factoryId, 0, $id, $pigModel::STATUS_SICK);
        // 已处理，待观察
        $treat = $pigModel->checkPigCount($factoryId, 0, $id, $pigModel::STATUS_OBSERVATION);
        // 治疗无效
        $treatmentIneffective = $pigModel->checkPigCount($factoryId, 0, $id, $pigModel::STATUS_INEFFECTIVE);

        return [
            'all_husbandry' => $all,
            'health_num' => $health,
            'suspectedhealthy_num' => $mayBeHealth,
            'sick_num' => $sick,
            'treat_num' => $treat,
            'treat_ineffective_num' => $treatmentIneffective,
            'avg_fmr' => $ratio2,
            'ratio_change' => $ratioChange,
            'today_weight_total' => $todayAvgWeight,
            'avg_weight_change' => $avgWeightChange
        ];
    }

    /**
     * @Description 获取栏的下拉选择列表
     * @param array $param
     * @time 2023/09/06 15:42:10
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * @author: zj
     */
    public function selectList(array $param)
    {
        $factoryId = request()->user_info['factory_id'];

        $fenceModel = new Fence();
        $query = $fenceModel->field("out_id as id,name")
            ->where('factory_id', $factoryId)
            ->where('out_barn_id', $param['barn_id'])
            ->where("delete_time", $fenceModel::IS_DELETE_NO);

        if ($param['name']) {
            $query->where('name', 'like', '%' . trim($param['name']) . '%');
        }

        return $query->order("out_id ASC")
            ->paginate([
                'list_rows' => $param['page_size'],
                'page' => $param['page']
            ])
            ->toArray();
    }

    /**
     * @Description 猪栏切换列表
     * @param array $param
     * @time 2023/09/05 17:28:50
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * @author: zj
     */
    public function getSwitchList(array $param)
    {
        $factoryId = request()->user_info['factory_id'];
        // 栋列表
        $buildModel = new Barn();
        $list = $buildModel->field("out_id as id,name")
            ->where('id', ">", $param['last_id'])
            ->where('factory_id', $factoryId)
            ->where("delete_time", $buildModel::IS_DELETE_NO)
            ->order("out_id ASC")
            ->limit($param['page_size'])
            ->select()
            ->toArray();
        if (!$list) {
            throw new LogicException("暂无数据");
        }

        // 猪栏列表
        $fenceModel = new Fence();
        foreach ($list as $key => &$value) {
            // 猪栏列表
            $fenceList = $fenceModel->field("out_id as id,name")
                ->where('factory_id', $factoryId)
                ->where('out_barn_id', $value['id'])
                ->where('delete_time', $fenceModel::IS_DELETE_NO)
                ->select()
                ->toArray();
            $value['children'] = $fenceList;
        }
        unset($value);

        return $list;
    }

    /**
     * @Description 编辑修改
     * @param int $factoryId
     * @param array $param
     * @time 2023/09/20 11:06:01
     * @return true
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * @author: zj
     */
    public function edit(int $factoryId, array $param)
    {
        $fenceModel = new Fence();
        $fence = $fenceModel->field('id,name,out_id,building_id')
            ->where('factory_id', $factoryId)
            ->where('id', $param['id'])
            ->where('delete_time', $fenceModel::IS_DELETE_NO)
            ->find();
        if (!$fence) {
            throw new LogicException('猪栏不存在');
        }
        $fence = $fence->toArray();
        $exist = $fenceModel->checkName($factoryId, $fence['building_id'], $param['name']);
        if ($exist && $exist != $fence['id']) {
            throw new LogicException('猪栋已存在此猪栏');
        }
        $fenceModel->where('id', $param['id'])
            ->update([
                'name' => $param['name'],
                'update_time' => request()->time()
            ]);

        return true;
    }

    /**
     * @Description
     * @author: zj
     * @param int $fence_id
     * @time 2024/03/20 15:59:06
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function todayFeedPlan(int $fence_id)
    {
        $factoryId = request()->user_info['factory_id'];

        $fenceModel = new Fence();
        $fence = $fenceModel->field('out_id,feed_plan_id,feed_base_time,is_loop')
            ->where('factory_id',$factoryId)
            ->where('out_id',$fence_id)
            ->where('delete_time',$fenceModel::IS_DELETE_NO)
            ->find();
        if (!$fence) {
            throw new LogicException('猪栏不存在');
        }
        if ($fence['is_loop']) {
            $feedPlanModel = new FeedPlan();
            $feedPlan = $feedPlanModel->alias('fp')
                ->join('feed f','f.out_id = fp.feed_id','left')
                ->field('fp.id,fp.out_id,fp.name,fp.feed_id,f.name as feed,feed_weight,fp.medicine_id,medicine_weight,fp.water_rate')
                ->where('fp.out_id',$fence['feed_plan_id'])
                ->where('fp.delete_time',$feedPlanModel::IS_DELETE_NO)
                ->find();
            if (!$feedPlan) {
                $feedPlan = [];
            }
            $feedPlan = $feedPlan->toArray();
        } else {
            $feedPlan = [];
            $feedPlanModel = new FourteenFeedPlan();
            $currentTime = request()->time();
            $days = ceil(($currentTime - $fence['feed_base_time']) / 14 * 86400);
            $fourteenFeedPlan = $feedPlanModel->field('id,out_id,name,day_id,remark')
                ->where('factory_id',$factoryId)
                ->where('out_id',$fence['feed_plan_id'])
                ->where('delete_time',$feedPlanModel::IS_DELETE_NO)
                ->find();
            $fourteenFeedPlan = $fourteenFeedPlan->toArray();
            $allFeedPlan = json_decode($fourteenFeedPlan['day_id']);


        }

        return $feedPlan;
    }

    /**
     * @Description 通过食谱id获取猪栏列表
     * @author: zj
     * @param array $param
     * @time 2024/03/27 09:57:43
     * @return mixed
     * @throws \think\db\exception\DbException
     */
    public function useCookBookBarn(array $param)
    {
        $factoryId = request()->user_info['factory_id'];
        $model = new Fence();
        $query = $model->alias('f')
            ->join('barn b','b.out_id = f.out_barn_id')
            ->field('f.out_id as id,f.name as fence,b.name as barn,f.feed_plan_id')
            ->where('f.factory_id',$factoryId)
            ->where('f.delete_time',$model::IS_DELETE_NO);
        if ($param['feed_plan_id']) {
            $query->where('f.feed_plan_id',$param['feed_plan_id']);
        }

        $list = $query->order('f.out_id DESC')
            ->paginate([
                'list_rows' => $param['page_size'],
                'page' => $param['page']
            ])
            ->toArray();

        $pigModel = new Pig();

        foreach ($list['data'] as &$value) {
            $total = $pigModel->checkPigCount($factoryId,0,$value['id']);
            $useCookbookCount = $pigModel->where('factory_id',$factoryId)
                ->where('out_fence_id',$value['id'])
                ->where('feed_plan_id',$param['feed_plan_id'])
                ->where('exit_time',$pigModel::IS_EXIT_NO)
                ->where('delete_time',$pigModel::IS_DELETE_NO)
                ->count();

            $value['total'] = $total;
            $value['use_count'] = $useCookbookCount;
        }
        unset($value);

        return $list;
    }

    /**
     * @Description 比较俩数大小
     * @author: zj
     * @param $num1
     * @param $num2
     * @time 2024/03/29 10:34:14
     * @return int
     */
    public function compare($num1,$num2)
    {
        if ($num1 < $num2) {
            return 2;
        } elseif ($num1 > $num2) {
            return 1;
        } else {
            return 0;
        }
    }

}